﻿
Imports osi.root.constants
Imports osi.root.connector
Imports osi.root.formation

Namespace error_handle
    Public Module error_distributor
        Private ReadOnly writers As object_unique_set(Of ierror_writer) = Nothing

        Sub New()
            writers = New object_unique_set(Of ierror_writer)()
            assert(insert(colorful_console_error_writer.instance))
            assert(insert(file_error_writer.instance))
        End Sub

        Public Function insert(ByVal w As ierror_writer) As Boolean
            Return writers.insert(w)
        End Function

        Public Sub clear()
            writers.clear()
        End Sub

        Public Function [erase](ByVal w As ierror_writer) As Boolean
            Return writers.erase(w)
        End Function

        <Runtime.CompilerServices.MethodImpl(Runtime.CompilerServices.MethodImplOptions.NoInlining)> _
        Private Function patchup_err_msg(ByVal err_type As error_type,
                                         ByVal err_type_char As Char,
                                         ByVal errmsg As String,
                                         ByVal additional_jump As Int32) As String
            Dim prefix As String = Nothing
            If err_type <= error_type.first OrElse err_type >= error_type.last OrElse err_type = error_type.other Then
                If err_type_char = character.null Then
                    prefix = character.x
                Else
                    prefix = Char.ToLower(err_type_char)
                End If
            Else
                prefix = Char.ToLower(error_type_char(err_type))
            End If
            prefix = strcat(prefix, seperator, short_time(), seperator)
            errmsg = strcat(prefix, errmsg)
            If err_type <> error_type.information Then
                errmsg.append(seperator, callingcode(additional_jump + 1))
            End If

            'keep one \r\n
            strrplc(errmsg, newline.incode(), character.newline)

            Return errmsg
        End Function

        <Runtime.CompilerServices.MethodImpl(Runtime.CompilerServices.MethodImplOptions.NoInlining)> _
        Friend Sub distribute(ByVal error_type As error_type,
                              ByVal error_type_char As Char,
                              ByVal msg As String,
                              ByVal additional_jump As Int32)
            msg = patchup_err_msg(error_type, error_type_char, msg, additional_jump + 1)
            utils.foreach(AddressOf writers.foreach,
                          Sub(ByRef writer As ierror_writer)
                              assert(Not writer Is Nothing)
                              If writer.select(error_type, error_type_char) Then
                                  writer.write(error_type, msg)
                              End If
                          End Sub)
        End Sub
    End Module
End Namespace
